home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / Terminal 2.2 / Project / Sources / Init.c < prev    next >
Text File  |  1992-01-17  |  14KB  |  550 lines

  1. /*
  2.     Terminal 2.2
  3.     "Init.c"
  4.  
  5.     Note: In the final application use ResEdit to clear the locked
  6.     bit of the CODE resource containing this segment. In this way the
  7.     initialisation code gets loaded high in the application heap and
  8.     all non-movable objects created (like strings, windows, master
  9.     pointers, buffers...) will be allocated at the start of the
  10.     application heap without any heap fragmentation when the
  11.     initialisation code is again unloaded.
  12. */
  13.  
  14. #ifdef THINK_C
  15. #include "MacHeaders"
  16. #endif
  17. #ifdef applec
  18. #pragma load ":(Objects):MacHeadersMPW"
  19. #pragma segment Init
  20. #endif
  21.  
  22. #include "Text.h"
  23. #include "Main.h"
  24. #include "Strings.h"
  25. #include "Utilities.h"
  26. #include "CRC.h"
  27. #include "Port.h"
  28. #include "File.h"
  29. #include "Macros.h"
  30.  
  31. /* Trap numbers */
  32.  
  33. #define TN_UnknownOS        0xA09F
  34. #define TN_CommToolbox        0xA08B
  35.  
  36. #define TN_UnknownTool        0xA89F
  37. #define TN_PopUpMenuSelect    0xA80B
  38. #define TN_WaitNextEvent    0xA860
  39. #define TN_ScriptUtil        0xA8B5
  40. #define TN_KeyTrans            0xA9C3
  41. #define TN_OSDispatch        0xA88F
  42.  
  43. #define INSET    2
  44. #define BAR        16            /* Scroll bar width */
  45. #define TLEFT    2            /* Default terminal window position */
  46. #define TTOP    40
  47. #define PLEFT    26            /* Default progress window position */
  48. #define PTOP    83
  49.  
  50. /* ----- Read information from 'CNFG' resource ------------------------- */
  51.  
  52. static void ReadConfig(void)
  53. {
  54.     register Configuration **h;
  55.  
  56.     /* Read configuration resource. If not available use defauts. */
  57.  
  58.     if (h = (Configuration **)GetResource('CNFG', 128)) {
  59.         HLock((Handle)h);
  60.         memcpy(&Config, *h, sizeof(Config));
  61.         GetFNum((**h).fontname, &Config.font);
  62.         ReleaseResource((Handle)h);
  63.     } else {
  64.         Config.font = monaco;
  65.         Config.size = 9;
  66.         Config.lines = 24;
  67.         Config.columns = 81;
  68.         Config.buffer = 0x8000;
  69.         Config.input = 0x2000;
  70.         Config.output = 64;
  71.         Config.script = 4096;
  72.     }
  73. }
  74.  
  75. /* ----- Read information from 'BNDL' resource ------------------------- */
  76.  
  77. typedef struct {
  78.     short    local;        /* Local ID */
  79.     short    actual;        /* Actual resource ID */
  80. } LOCAL;
  81.  
  82. typedef struct {
  83.     long    type;        /* Resource type 'ICN#' or 'FREF' */
  84.     short    count;        /* Number of resources - 1 (must be 2) */
  85.     LOCAL    id[3];
  86. } TYPE;
  87.  
  88. typedef struct {
  89.     long    signature;    /* Signature of the application */
  90.     short    version;    /* Resource ID of version data */
  91.     short    types;        /* Number of resource types - 1 (must be 1) */
  92.     TYPE    info[2];
  93. } BUNDLE;
  94.  
  95. typedef struct {
  96.     long    type;        /* File type */
  97.     short    local;        /* Local ID for icon list */
  98. } FREF;
  99.  
  100. static void Bundle(void)
  101. {
  102.     register BUNDLE **h;
  103.     register BUNDLE *p;
  104.     register FREF **f;
  105.     register short i, j;
  106.  
  107.     Application.version = 0;
  108.     Application.icon = 128;
  109.     Application.signature =
  110.         Application.otype =
  111.         Application.btype =
  112.         Application.stype =
  113.         Application.ztype = '????';
  114.  
  115.     if (h = (BUNDLE **)GetIndResource('BNDL', 1)) {
  116.         HLock((Handle)h);
  117.         p = *h;
  118.         Application.signature = p->signature;
  119.         Application.version = p->version;
  120.         for (i = 0; i <= p->types; i++)
  121.             switch (p->info[i].type) {
  122.             case 'ICN#':
  123.                 for (j = 0; j <= p->info[i].count; j++)
  124.                     if (p->info[i].id[j].local == 0) {
  125.                         Application.icon = p->info[i].id[j].actual;
  126.                         break;
  127.                     }
  128.                 break;
  129.             case 'FREF':
  130.                 for (j = 0; j <= p->info[i].count; j++) {
  131.                     if (f = (FREF **)
  132.                             GetResource('FREF', p->info[i].id[j].actual)) {
  133.                         register long t = (**f).type;
  134.                         ReleaseResource((Handle)f);
  135.                         switch (p->info[i].id[j].local) {
  136.                         case 1:    /* Options */
  137.                             Application.otype = t;
  138.                             break;
  139.                         case 2:    /* MacBinary */
  140.                             Application.btype = t;
  141.                             break;
  142.                         case 3:    /* Script */
  143.                             Application.stype = t;
  144.                             break;
  145.                         case 4:    /* Z-modem part */
  146.                             Application.ztype = t;
  147.                             break;
  148.                         }
  149.                     }
  150.                 }
  151.                 break;
  152.             }
  153.         ReleaseResource((Handle)h);
  154.     }
  155. }
  156.  
  157. /* ----- Make sure window is on desktop -------------------------------- */
  158.  
  159. static void WindowScreen(
  160.     Point *p,
  161.     short dh,
  162.     short dv)
  163. {
  164.     RgnHandle rgn;
  165.  
  166.     if (!(rgn = NewRgn()))
  167.         return;
  168.     SetRectRgn(rgn, p->h, p->v - 15, p->h + 50, p->v + 15);
  169.     UnionRgn(GrayRgn, rgn, rgn);
  170.     if (!EqualRgn(GrayRgn, rgn)) {
  171.         p->h = dh;
  172.         p->v = dv;
  173.     }
  174.     DisposeRgn(rgn);
  175. }
  176.  
  177. /* ----- Read options -------------------------------------------------- */
  178.  
  179. static void ReadOptions(void)
  180. {
  181.     short err;
  182.     short volume;
  183.     long directory, scriptDirectory;
  184.     long count;
  185.     Byte volname[28];
  186.  
  187.     /* Get volume and folder where application is */
  188.  
  189.     {
  190.         WDPBRec vol;
  191.  
  192.         vol.ioCompletion = 0;
  193.         vol.ioNamePtr = 0;
  194.         if (PBHGetVol(&vol, FALSE)) {
  195.             volume = Mac.sysVRefNum;
  196.             directory = 2;
  197.         } else {
  198.             volume = vol.ioWDVRefNum;
  199.             directory = vol.ioWDDirID;
  200.         }
  201.         VolumeId(volname, &volume);
  202.     }
  203.  
  204.     /* If there is a script folder in the application folder use it,
  205.     else use application folder as script folder */
  206.  
  207.     {
  208.         CInfoPBRec pb;
  209.  
  210.         scriptDirectory = directory;
  211.         pb.dirInfo.ioCompletion = 0;
  212.         pb.dirInfo.ioNamePtr = (StringPtr)MyString(STR_G, G_SCRIPTFOLDER);
  213.         pb.dirInfo.ioVRefNum = volume;
  214.         pb.dirInfo.ioFDirIndex = 0;
  215.         pb.dirInfo.ioDrDirID = directory;
  216.         if (!PBGetCatInfo(&pb, FALSE) && (pb.dirInfo.ioFlAttrib & 0x10))
  217.             scriptDirectory = pb.dirInfo.ioDrDirID;
  218.     }
  219.  
  220.     /* Read settings file from script folder */
  221.  
  222.     {
  223.         short r;
  224.  
  225.         if (!(err = OpenFile(volume, scriptDirectory,
  226.                 MyString(STR_G,G_SETTINGS), &r))) {
  227.             count = sizeof(Settings);
  228.             err = FSRead(r, &count, (Ptr)&Settings);
  229.             FSClose(r);
  230.         }
  231.     }
  232.  
  233.     /* If a valid settings file is found, use it, else use defaults */
  234.  
  235.     if (err || count != sizeof(Settings) || Settings.version != SETTINGS ||
  236.             CalcCRC((Byte *)&Settings + sizeof(short),
  237.             sizeof(Settings) - sizeof(short), 0) != Settings.crc) {
  238.  
  239.         /* Communication options */
  240.  
  241.         *Settings.portName = 0;
  242.         Settings.portSetup = baud2400+stop10+noParity+data8;
  243.         Settings.dropDTR = FALSE;
  244.  
  245.         /* TEXT file send options */
  246.  
  247.         Settings.prompt[0] = 0;
  248.         Settings.linedelay = 0;
  249.         Settings.chardelay = 0;
  250.         Settings.handshake = 0;
  251.  
  252.         /* Binary file transfer options */
  253.  
  254.         Settings.Binary = TRUE;
  255.         memcpy(Settings.volumeName, volname, volname[0] + 1);
  256.         Settings.volume = volume;
  257.         Settings.directory = directory;
  258.         Settings.protocol = 0;
  259.         Settings.ZModem = FALSE;
  260.         Settings.ZAutoReceive = FALSE;
  261.  
  262.         /* XYModem options */
  263.  
  264.         Settings.XModemtimeout = 600;    /* 10 s */
  265.         Settings.XModemCRC = TRUE;
  266.         Settings.XModem1K = 0;
  267.         Settings.batch = 0;
  268.  
  269.         /* ZModem options */
  270.  
  271.         Settings.ZEscapeCtl = FALSE;
  272.         Settings.ZTimeout = 600;        /* 10 s */
  273.         Settings.ZBuffer = 0;
  274.         Settings.ZRetries = 10;
  275.         Settings.ZPacket = 1024;
  276.         Settings.ZWindow = 0;
  277.         Settings.Zcrcq = 0;
  278.  
  279.         /* Terminal options */
  280.  
  281.         Settings.localEcho = FALSE;
  282.         Settings.echo = FALSE;
  283.         Settings.autoLF = FALSE;
  284.         Settings.save = TRUE;
  285.         /* Settings.scriptVolume */
  286.         /* Settings.scriptDirectory */
  287.         Settings.startVName[0] = 0;
  288.         Settings.startVolume = 0;
  289.         Settings.startDirectory = 0;
  290.         Settings.startName[0] = 0;
  291.  
  292.         /* Other options */
  293.  
  294.         Settings.textCreator = 'PEDT';
  295.         Settings.binType = TEXT;
  296.         Settings.binCreator = 'PEDT';
  297.         Settings.backspace = 0x08;
  298.         Settings.escape = 0x1B;
  299.         Settings.beep = FALSE;
  300.         Settings.ctrl = 0;
  301.  
  302.         /* Window positions */
  303.  
  304.         Settings.terminalWindow.h = TLEFT;
  305.         Settings.terminalWindow.v = TTOP;
  306.         Settings.progressWindow.h = PLEFT;
  307.         Settings.progressWindow.v = PTOP;
  308.     } else {
  309.         /* Make sure left corner of windows is on desktop */
  310.         WindowScreen(&Settings.terminalWindow, TLEFT, TTOP);
  311.         WindowScreen(&Settings.progressWindow, PLEFT, PTOP);
  312.     }
  313.  
  314.     Settings.scriptVolume = volume;
  315.     Settings.scriptDirectory = scriptDirectory;
  316.     Settings.dirty = FALSE;
  317.  
  318.     /* Make sure volume reference numbers and volume names are ok.
  319.     This is necessary if booting from different disks. */
  320.  
  321.     Settings.volume = 0;
  322.     if (VolumeId(Settings.volumeName, &Settings.volume)) {
  323.         Settings.volume = volume;
  324.         memcpy(Settings.volumeName, volname, volname[0] + 1);
  325.         Settings.directory = directory;
  326.     }
  327.     Settings.startVolume = 0;
  328.     if (Settings.startVName[0])
  329.         VolumeId(Settings.startVName, &Settings.startVolume);
  330. }
  331.  
  332. /* ----- Set up new text record ---------------------------------------- */
  333.  
  334. static long InitTextRecord(
  335.     register TextRecord *p,
  336.     register long size)
  337. {
  338.     p->lines = 1;
  339.     p->firstChar = p->newChar = p->length = p->viewChar = p->viewLine = 0;
  340.     if (size = (p->text = (Byte *)NewPtr(size)) ? (p->size = size) : 0)
  341.         (p->text)[0] = '\015';
  342.     return size;
  343. }
  344.  
  345. /* ----- Set up script menu items -------------------------------------- */
  346.  
  347. static void ScriptsInit(void)
  348. {
  349.     register MenuHandle mh;
  350.     register short i;
  351.     register Byte *p;
  352.     register Byte *q;
  353.     register Byte *suffix = (Byte *)MyString(STR_G, G_SUFFIX);
  354.     Byte name[256];
  355.     HParamBlockRec pb;
  356.     short menuitem = 2;
  357.  
  358.     if (!(mh = GetMenu(SCRIPT)))
  359.         return;
  360.     for (i = 1; ; i++) {
  361.         pb.ioParam.ioCompletion = 0;
  362.         pb.ioParam.ioVRefNum = Settings.scriptVolume;
  363.         pb.fileParam.ioDirID = Settings.scriptDirectory;
  364.         pb.ioParam.ioNamePtr = (StringPtr)name;
  365.         pb.fileParam.ioFDirIndex = i;
  366.         if (PBHGetFInfo(&pb, FALSE))
  367.             break;
  368.         if (pb.fileParam.ioFlFndrInfo.fdType == TEXT)
  369.             for (p = name + *name, q = suffix + *suffix; ; --p, --q) {
  370.                 if (q == suffix) {            /* Show the file */
  371.                     *name -= *suffix;        /* Strip suffix */
  372.                     /* This AppendMenu() followed by SetItem() is necessary
  373.                     if there are any of the menu meta characters ( ';' '^'
  374.                     '!' '<' '/' '(' ) in the name. */
  375.                     AppendMenu(mh, "\p ");
  376.                     SetItem(mh, ++menuitem, name);
  377.                     break;
  378.                 }
  379.                 if (p == name || *q != *p)    /* Don't show file */
  380.                     break;
  381.             }
  382.     }
  383. }
  384.  
  385. /* ----- Create new document record ------------------------------------ */
  386.  
  387. static DocumentPeek NewDocument(void)
  388. {
  389.     register DocumentPeek window;
  390.     FontInfo info;
  391.     Rect r;
  392.  
  393.     if (window = (DocumentPeek)NewPtr(sizeof(DocumentRecord))) {
  394.  
  395.         /* Make new window and get font characteristics */
  396.  
  397.         r = QD(screenBits.bounds);    /* Will be adjusted later */
  398.         if (!NewWindow((void *)window, &r,
  399.                 MyString(STR_G, G_TERMINAL),
  400.                 FALSE, noGrowDocProc, (WindowPtr)-1L, TRUE, 0)) {
  401.             DisposPtr((Ptr)window);
  402.             return 0;
  403.         }
  404.         SetPort((GrafPtr)window);
  405.         TextFont(Config.font);
  406.         TextFace(0);
  407.         TextMode(srcOr);
  408.         TextSize(Config.size);
  409.         GetFontInfo(&info);
  410.         info.widMax = CharWidth('M');    /* widMax not always correct */
  411.  
  412.         /* Initialize document fields */
  413.  
  414.         if (!InitTextRecord(&window->buf, Config.buffer)) {
  415.             DisposeWindow((WindowPtr)window);
  416.             return 0;
  417.         }
  418.         window->file = window->volume = 0;
  419.         window->length = 0;
  420.  
  421.         /* Adjust window size and position */
  422.  
  423.         r.top = 21;
  424.         r.left = 0;
  425.         r.bottom = r.top + 2*INSET + Config.lines * (window->height = 
  426.             info.ascent + info.descent + info.leading);
  427.         r.right = r.left + 2*INSET + Config.columns * info.widMax;
  428.         window->rect = r;
  429.         InsetRect(&window->rect, INSET, INSET);
  430.         window->cursor0.v = window->rect.top + info.ascent;
  431.         window->cursor0.h = window->rect.left;
  432.         window->cursor = window->cursor0;
  433.         window->linesPage = Config.lines;
  434.         window->character.top = - info.ascent;
  435.         window->character.left = 0;
  436.         window->character.bottom = info.descent;
  437.         window->character.right = info.widMax;
  438.         r.top = 0;
  439.         r.right += BAR - 1;
  440.         OffsetRect(&r,Settings.terminalWindow.h,Settings.terminalWindow.v);
  441.         MoveWindow((WindowPtr)window, r.left, r.top, FALSE);
  442.         SizeWindow((WindowPtr)window, r.right - r.left,
  443.             r.bottom - r.top, TRUE);
  444.  
  445.         /* Create window controls */
  446.  
  447.         r.top = window->rect.top - INSET - 1;
  448.         r.left = window->rect.right + INSET;
  449.         r.bottom = window->rect.bottom + INSET + 1;
  450.         r.right = r.left + BAR;
  451.         if (window->vs = NewControl((WindowPtr)window, &r, EmptyStr, TRUE,
  452.                 0, 0, 0, scrollBarProc, 0)) {
  453.             r.top = 2;
  454.             r.left = 2;
  455.             r.bottom = r.top + 16;
  456.             r.right = r.left + 30;
  457.             window->messOk = NewControl((WindowPtr)window, &r, "\p\022",
  458.                 FALSE, 0, 0, 0, pushButProc, 0);
  459.             window->messRect.top = 1;
  460.             window->messRect.left = 34;
  461.             window->messRect.bottom = window->rect.top - INSET - 2;
  462.             window->messRect.right = window->rect.right + INSET + BAR
  463.                 - 2;
  464.             window->mess[0] = 0;
  465.             ShowWindow((WindowPtr)window);
  466.         } else {
  467.             DisposeWindow((WindowPtr)window);
  468.             return 0;
  469.         }
  470.     }
  471.     return window;
  472. }
  473.  
  474. /* ----- See if a given trap is available ------------------------------- */
  475.  
  476. static Boolean TrapAvailable(
  477.     register short num,
  478.     register short type)
  479. {
  480.     if (type == ToolTrap &&
  481.             Mac.machineType > envMachUnknown &&
  482.             Mac.machineType < envMacII) {
  483.         num &= 0x03FF;
  484.         if (num > 0x01FF)
  485.             num = TN_UnknownTool;
  486.     }
  487.     return NGetTrapAddress(num, type) !=
  488.         GetTrapAddress((type == OSTrap) ? TN_UnknownOS : TN_UnknownTool);
  489. }
  490.  
  491. /* ----- One time initialization ---------------------------------------- */
  492.  
  493. #ifdef USECTB
  494.     pascal OSErr InitCRM(void);
  495. #endif
  496.  
  497. Boolean Init(void)
  498. {
  499.     register short err;
  500.     register Handle h;
  501.     pascal void Crash();
  502.     EventRecord event;
  503.  
  504.     for (err = 0; err < 4; ++err)
  505.         MoreMasters();
  506.     InitGraf(&QD(thePort));
  507.     InitFonts();
  508.     InitWindows();
  509.     InitMenus();
  510.     TEInit();
  511.     InitDialogs(Crash);
  512.     InitCursor();
  513.     for (err = 0; err < 3; ++err)
  514.         EventAvail(everyEvent, &event);
  515.     TerminalWindow = 0;
  516.     SysEnvirons(1, &Mac);
  517.     if (Mac.machineType < 0 ||
  518.         !TrapAvailable(TN_PopUpMenuSelect, ToolTrap)) {    /* Old Mac */
  519.         Error(0, MyString(STR_M, M_OLD));
  520.         return TRUE;
  521.     }
  522.     WNE = TrapAvailable(TN_WaitNextEvent, ToolTrap);
  523.     KCHR = (TrapAvailable(TN_ScriptUtil, ToolTrap) &&
  524.             TrapAvailable(TN_KeyTrans, ToolTrap)) ?
  525.         GetResource('KCHR', GetScript(smRoman, smScriptKeys)) : 0;
  526.     MFmemory = TrapAvailable(TN_OSDispatch, ToolTrap);
  527. #ifdef USECTB
  528.     if (CTB = TrapAvailable(TN_CommToolbox, OSTrap))
  529.         InitCRM();
  530. #endif
  531.     Background = FALSE;
  532.     ReadConfig();
  533.     ReadOptions();
  534.     Bundle();
  535.     if (!(h = GetNewMBar(MENUBAR)))
  536.         return TRUE;
  537.     SetMenuBar(h);
  538.     DisposHandle(h);
  539.     if (h = (Handle)GetMHandle(APPLE))
  540.         AddResMenu((MenuHandle)h, 'DRVR');
  541.     ScriptsInit();
  542.     DrawMenuBar();
  543.     TerminalWindow = NewDocument();
  544.     if (TerminalWindow &&
  545.             (err = SerialOpen(Settings.portName, Settings.portSetup,
  546.                 Settings.handshake)))
  547.         Error(err, EmptyStr);
  548.     return TerminalWindow == 0;
  549. }
  550.